package com.yuanmei.charts;

import android.content.Context;
import android.text.Html;
import android.text.Spanned;
import android.util.Log;

import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.data.CombinedData;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import com.tictactec.ta.lib.MAType;
import com.tictactec.ta.lib.MInteger;
import com.tictactec.ta.lib.RetCode;
import com.yuanmei.views.R;
import com.yuanmei.common.Utils;
import com.tictactec.ta.lib.Core;

import java.util.ArrayList;
import java.util.List;

public class KDJChartDataSet implements TaChartData {
    private static final String TAG = "KDJChart";
    private List<Entry> mKValueList;
    private List<Entry> mDValueList;
    private List<Entry> mJValueList;
    private List<BarEntry> mZBarList;

    private List<String> mXAxisDates;
    private CombinedData mKDJCombineData;
    private Context mContext;
    private KLineChartDataSet mRawDataSet;


    private Float[] getHighAndLowByK(Integer begin, Integer end) {
        if (begin < 0)
            begin = 0;

        float high = mRawDataSet.getHigh(begin);
        float low = mRawDataSet.getLow(begin);
        Float[] wrs = new Float[2];
        for (int i = begin + 1; i < end; i++) {
            float quoteHigh = mRawDataSet.getHigh(i);
            float quoteLow = mRawDataSet.getLow(i);
            high = high > quoteHigh ? high : quoteHigh;
            low = low < quoteLow ? low : quoteLow;
        }

        wrs[0] = high;
        wrs[1] = low;
        return wrs;
    }

    public KDJChartDataSet(Context context, KLineChartDataSet rawDataSet) {
        mContext = context;
        mRawDataSet = rawDataSet;

        mKValueList = new ArrayList<>();
        mDValueList = new ArrayList<>();
        mJValueList = new ArrayList<>();
        mZBarList = new ArrayList<>();
        mXAxisDates = new ArrayList<>();

        float k = 50.0f;
        float d = 50.0f;
        float j = 0.0f;
        float rSV = 0.0f;

        int period = 9;

        float high = mRawDataSet.getHigh(0);
        float low = mRawDataSet.getLow(0);

        int inLen = mRawDataSet.getXAxisSize();
        float[] inHigh = new float[inLen];
        float[] inLow = new float[inLen];
        float[] inClose = new float[inLen];

        for (int i = 0; i < mRawDataSet.getXAxisSize(); i++) {
            mXAxisDates.add(mRawDataSet.getXAxisLabel(i));
            inHigh[i]  = mRawDataSet.getHigh(i);
            inLow[i]   = mRawDataSet.getLow(i);
            inClose[i] = mRawDataSet.getClose(i);

//            float currentHigh = mRawDataSet.getHigh(0);
//            float currentLow = mRawDataSet.getLow(0);
//            float currentClose = mRawDataSet.getClose(0);
//
//            if (i > 0) {
//                if (period == 0) {
//                    high = high > currentHigh ? high : currentHigh;
//                    low = low < currentLow ? low : currentLow;
//                } else {
//                    int t = i - period + 1;
//                    Float[] wrs = getHighAndLowByK(t, i);
//                    high = wrs[0];
//                    low = wrs[1];
//                }
//            }
//            if (high != low) {
//                rSV = (currentClose - low) / (high - low) * 100;
//            } else {
//                rSV = 0;
//            }
//            k = k * 2 / 3 + rSV / 3;
//            d = d * 2 / 3 + k / 3;
//            j = (3 * k) - (2 * d);
//
//            //其他软件没有大于100小于0的值，但是我算出来确实有，其它软件在0和100的时候出现直线，怀疑也是做了处理
//            j = j < 0 ? 0 : j;
//            j = j > 100 ? 100 : j;
//
//            mKValueList.add(new Entry(i, k));
//            mDValueList.add(new Entry(i, d));
//            mJValueList.add(new Entry(i, j));

            mKValueList.add(new Entry(i, 0));
            mDValueList.add(new Entry(i, 0));
            mJValueList.add(new Entry(i, 0));
            mZBarList.add(new BarEntry(i, 0));
        }

        Core ta_core = new Core();
        double[] outSlowK = new double[inLen];
        double[] outSlowD = new double[inLen];
        MInteger begin = new MInteger();
        MInteger outLen = new MInteger();

        RetCode retCode = ta_core.stoch(0, inLen - 1, inHigh, inLow,
                inClose, 9, 5,
                MAType.Ema, 5, MAType.Ema,
                begin, outLen, outSlowK, outSlowD);
        if (retCode == RetCode.Success) {
//            Log.d(TAG,"KDJ OK Output Period: " + begin.value + " -- " +
//                    (begin.value + outLen.value - 1));
            for (int i = begin.value; i < begin.value + outLen.value; i++) {
                double out_k = outSlowK[i - begin.value];
                double out_d = outSlowD[i - begin.value];
                double out_j = (3 * k) - (2 * d);
//                Log.d(TAG, "KDJ i=" + i + ", k=" + (float) out_k  + ", d=" +(float) out_d
//                    + ", out_j=" + (float) out_j);
                mKValueList.get(i).setY((float) out_k);
                mDValueList.get(i).setY((float) out_d);
                mJValueList.get(i).setY((float) out_j);
            }
        } else {
            Log.d(TAG,"KDJ ta-lib calc error: " + retCode);
        }

        BarDataSet barSet = new BarDataSet(mZBarList, "");
        barSet.setDrawValues(false);
        BarData barData = new BarData(barSet);

        ArrayList<ILineDataSet> lineDataSet = new ArrayList<>();
        LineDataSet kSet = new LineDataSet(mKValueList, "K");
        TaLib.setCommonMaStyle(kSet);
        kSet.setHighlightEnabled(true);
        kSet.setDrawHorizontalHighlightIndicator(true);
        kSet.setDrawVerticalHighlightIndicator(true);
        kSet.setHighLightColor(mContext.getResources().getColor(R.color.border_color));
        kSet.setColor(mContext.getResources().getColor(R.color.ma5));
        lineDataSet.add(kSet);

        LineDataSet dSet = new LineDataSet(mDValueList, "D");
        TaLib.setCommonMaStyle(dSet);
        dSet.setColor(mContext.getResources().getColor(R.color.ma10));
        lineDataSet.add(dSet);

        LineDataSet jSet = new LineDataSet(mDValueList, "J");
        TaLib.setCommonMaStyle(jSet);
        jSet.setColor(mContext.getResources().getColor(R.color.ma10));
        lineDataSet.add(jSet);

        LineData linesData = new LineData(lineDataSet);

        mKDJCombineData = new CombinedData();
        mKDJCombineData.setData(barData);
        mKDJCombineData.setData(linesData);
    }

    @Override
    public int getXAxisSize() {
        return mXAxisDates.size();
    }

    @Override
    public String getXAxisLabel(int index) {
        String date = "None";
        if (index >= 0 && index < mXAxisDates.size()) {
            date = String.valueOf(mXAxisDates.get(index));
        }
        return date;
    }

    @Override
    public Spanned getDescription(int index) {
        String description = "KDJ K:";
        if (index >= 0 && index < mKValueList.size()) {
            description += Utils.priceToDecimalString(mKValueList.get(index).getY());
        }

        String dif = ", D:";
        if (index >= 0 && index < mDValueList.size()) {
            dif += Utils.priceToDecimalString(mDValueList.get(index).getY());
        }

        String dea = ", J:";
        if (index >= 0 && index < mJValueList.size()) {
            dea += Utils.priceToDecimalString(mJValueList.get(index).getY());
        }
//        return  description + dif + dea;
        return Html.fromHtml(description + dif + dea);
    }

    @Override
    public List<String> getXAxisLabelList() {
        return mXAxisDates;
    }

    @Override
    public CombinedData getTaChartData() {
        return mKDJCombineData;
    }
}
